﻿using CK.Sprite.Cache;
using CK.Sprite.Framework;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace CK.Sprite.Form.Core
{
    public class SpriteFormService : DomainService
    {
        public ICacheSendNotice CacheSendNotice => LazyGetRequiredService(ref _cacheSendNotice);
        private ICacheSendNotice _cacheSendNotice;

        public SpriteFormLocalCache SpriteFormLocalCache => LazyGetRequiredService(ref _spriteFormLocalCache);
        private SpriteFormLocalCache _spriteFormLocalCache;

        public SpriteViewLocalCache SpriteViewLocalCache => LazyGetRequiredService(ref _spriteViewLocalCache);
        private SpriteViewLocalCache _spriteViewLocalCache;

        public SpriteObjectLocalCache SpriteObjectLocalCache => LazyGetRequiredService(ref _spriteObjectLocalCache);
        private SpriteObjectLocalCache _spriteObjectLocalCache;

        private string _applicationCode;
        private Dictionary<Guid, Guid> idMapes;

        public SpriteFormService()
        {
            idMapes = new Dictionary<Guid, Guid>();
        }

        #region SpriteForm Operate

        public async Task AddSpriteFormAsync(SpriteFormCreateDto spriteFormCreateDto)
        {
            var spriteForm = Mapper.Map<SpriteFormCreateDto, SpriteForm>(spriteFormCreateDto);
            spriteForm.Id = Guid.NewGuid();
            spriteForm.Version = Guid.NewGuid();

            await _serviceProvider.DoDapperServiceAsync(DefaultDbConfig, async (unitOfWork) =>
            {
                var spriteFormRepository = new GuidRepositoryBase<SpriteForm>(unitOfWork);

                _applicationCode = spriteFormCreateDto.ApplicationCode;
                return await spriteFormRepository.InsertAsync(spriteForm);
            });
            CacheSendNotice.SendClearCache($"{CommonConsts.SpriteFormCachePreKey}-{_applicationCode}_{CommonConsts.SpriteFormCacheKey}");
        }

        public async Task UpdateSpriteFormAsync(SpriteFormUpdateDto spriteFormUpdateDto)
        {
            await _serviceProvider.DoDapperServiceAsync(DefaultDbConfig, async (unitOfWork) =>
            {
                var spriteFormRepository = new GuidRepositoryBase<SpriteForm>(unitOfWork);
                var spriteForm = await spriteFormRepository.GetAsync(spriteFormUpdateDto.Id);
                if (spriteForm == null)
                {
                    throw new SpriteException("未找到SpriteForm数据信息");
                }
                Mapper.Map(spriteFormUpdateDto, spriteForm);
                spriteForm.Version = Guid.NewGuid();
                _applicationCode = spriteForm.ApplicationCode;
                return await spriteFormRepository.UpdateAsync(spriteForm);
            });
            CacheSendNotice.SendClearCache($"{CommonConsts.SpriteFormCachePreKey}-{_applicationCode}_{CommonConsts.SpriteFormCacheKey}");
        }

        public async Task DeleteSpriteForm(Guid id)
        {
            var spriteForm = await _serviceProvider.DoDapperServiceAsync(DefaultDbConfig, async (unitOfWork) =>
            {
                GuidRepositoryBase<SpriteForm> spriteFormRepository = new GuidRepositoryBase<SpriteForm>(unitOfWork);
                var dbSpriteForm = await spriteFormRepository.GetAsync(id);
                if (dbSpriteForm == null)
                {
                    throw new SpriteException("未找到SpriteForm数据信息");
                }

                return dbSpriteForm;
            });

            _applicationCode = spriteForm.ApplicationCode;

            var formViewVueInfos = new FormViewVueInfos();

            var spriteFormCaches = SpriteFormLocalCache.GetAllDict(spriteForm.ApplicationCode);
            var spriteViewCaches = SpriteViewLocalCache.GetAllDict(spriteForm.ApplicationCode);

            CalculateFormViewVueInfo(formViewVueInfos, spriteFormCaches, spriteViewCaches, spriteForm.Id, true);
            List<Guid> Ids = new List<Guid>();
            if (formViewVueInfos.FormDatas.Count > 0)
            {
                Ids.AddRange(formViewVueInfos.FormDatas.Select(r => r.Id));
            }

            if (formViewVueInfos.ViewDatas.Count > 0)
            {
                Ids.AddRange(formViewVueInfos.ViewDatas.Select(r => r.Id));
            }

            if (Ids.Count == 0)
            {
                return;
            }

            await _serviceProvider.DoDapperServiceAsync(DefaultDbConfig, async (unitOfWork) =>
            {
                ISpriteCommonRepository spriteCommonRepository = ConnectionFactory.GetConnectionProvider(DefaultDbConfig.ConnectionType).GetRepository<ISpriteCommonRepository>(unitOfWork);
                await spriteCommonRepository.DeleteSpriteFormOrView(Ids);
            });
            CacheSendNotice.SendClearCache($"{CommonConsts.SpriteFormCachePreKey}-{_applicationCode}_{CommonConsts.SpriteFormCacheKey}");
            CacheSendNotice.SendClearCache($"{CommonConsts.SpriteFormCachePreKey}-{_applicationCode}_{CommonConsts.SpriteViewCacheKey}");
        }

        public async Task DeleteSelfSpriteForm(Guid id)
        {
            var spriteForm = await _serviceProvider.DoDapperServiceAsync(DefaultDbConfig, async (unitOfWork) =>
            {
                GuidRepositoryBase<SpriteForm> spriteFormRepository = new GuidRepositoryBase<SpriteForm>(unitOfWork);
                var dbSpriteForm = await spriteFormRepository.GetAsync(id);
                if (dbSpriteForm == null)
                {
                    throw new SpriteException("未找到SpriteForm数据信息");
                }

                return dbSpriteForm;
            });

            _applicationCode = spriteForm.ApplicationCode;
            List<Guid> Ids = new List<Guid>() { id };

            if (Ids.Count == 0)
            {
                return;
            }

            await _serviceProvider.DoDapperServiceAsync(DefaultDbConfig, async (unitOfWork) =>
            {
                ISpriteCommonRepository spriteCommonRepository = ConnectionFactory.GetConnectionProvider(DefaultDbConfig.ConnectionType).GetRepository<ISpriteCommonRepository>(unitOfWork);
                await spriteCommonRepository.DeleteSpriteFormOrView(Ids);
            });
            CacheSendNotice.SendClearCache($"{CommonConsts.SpriteFormCachePreKey}-{_applicationCode}_{CommonConsts.SpriteFormCacheKey}");
            CacheSendNotice.SendClearCache($"{CommonConsts.SpriteFormCachePreKey}-{_applicationCode}_{CommonConsts.SpriteViewCacheKey}");
        }

        public async Task<List<SpriteForm>> GetSpriteFormAsync(bool isTemplate, string applicationCode = "Default", int? formType = null, string filter = default, string category = default)
        {
            return await _serviceProvider.DoDapperServiceAsync(DefaultDbConfig, async (unitOfWork) =>
            {
                var spriteCommonRepository = ConnectionFactory.GetConnectionProvider(DefaultDbConfig.ConnectionType).GetRepository<ISpriteCommonRepository>(unitOfWork);
                ExpressSqlModel expressSqlModel = new ExpressSqlModel()
                {
                    SqlExpressType = ESqlExpressType.And,
                    Children = new List<ExpressSqlModel>()
                     {
                         new ExpressSqlModel()
                         {
                            Field = "ApplicationCode",
                            ConditionType = EConditionType.等于,
                            Value = applicationCode,
                            SqlExpressType = ESqlExpressType.Condition
                         }
                     }
                };
                expressSqlModel.Children.Add(new ExpressSqlModel()
                {
                    Field = "IsTemplate",
                    ConditionType = EConditionType.等于,
                    Value = isTemplate,
                    SqlExpressType = ESqlExpressType.Condition
                });
                if (formType.HasValue)
                {
                    expressSqlModel.Children.Add(new ExpressSqlModel()
                    {
                        Field = "FormType",
                        ConditionType = EConditionType.等于,
                        Value = formType.Value,
                        SqlExpressType = ESqlExpressType.Condition
                    });
                }
                if (!string.IsNullOrEmpty(category))
                {
                    expressSqlModel.Children.Add(new ExpressSqlModel()
                    {
                        Field = "Category",
                        ConditionType = EConditionType.等于,
                        Value = category,
                        SqlExpressType = ESqlExpressType.Condition
                    });
                }
                if (!string.IsNullOrEmpty(filter))
                {
                    expressSqlModel.Children.Add(new ExpressSqlModel()
                    {
                        SqlExpressType = ESqlExpressType.Or,
                        Children = new List<ExpressSqlModel>()
                         {
                             new ExpressSqlModel()
                             {
                                Field = "Name",
                                ConditionType = EConditionType.Like,
                                Value = filter,
                                SqlExpressType = ESqlExpressType.Condition
                             },
                             new ExpressSqlModel()
                             {
                                Field = "Description",
                                ConditionType = EConditionType.Like,
                                Value = filter,
                                SqlExpressType = ESqlExpressType.Condition
                             },
                         }
                    });
                }
                var result = await spriteCommonRepository.GetCommonList2<SpriteForm>("SpriteForms", expressSqlModel);
                return result;
            });
        }

        public async Task SetFormTemplate(Guid id, bool isTemplate)
        {
            await _serviceProvider.DoDapperServiceAsync(DefaultDbConfig, async (unitOfWork) =>
            {
                GuidRepositoryBase<SpriteForm> spriteFormRepository = new GuidRepositoryBase<SpriteForm>(unitOfWork);
                var findSpriteForm = await spriteFormRepository.GetAsync(id);
                if (findSpriteForm == null)
                {
                    throw new SpriteException("未找到SpriteForm数据信息");
                }

                if (findSpriteForm.IsTemplate == isTemplate)
                {
                    throw new SpriteException($"表单已处于{(isTemplate ? "模版" : "非模板")}状态");
                }

                findSpriteForm.IsTemplate = isTemplate;
                await spriteFormRepository.UpdateAsync(findSpriteForm);

                _applicationCode = findSpriteForm.ApplicationCode;
            });
            CacheSendNotice.SendClearCache($"{CommonConsts.SpriteFormCachePreKey}-{_applicationCode}_{CommonConsts.SpriteFormCacheKey}");
        }

        public async Task<List<string>> GetCategorysAsync()
        {
            return await _serviceProvider.DoDapperServiceAsync(DefaultDbConfig, async (unitOfWork) =>
            {
                var spriteFormRepository = ConnectionFactory.GetConnectionProvider(DefaultDbConfig.ConnectionType).GetRepository<ISpriteFormRepository>(unitOfWork);
                return await spriteFormRepository.GetCategorysAsync("SpriteForms");
            });
        }

        #endregion

        #region FormItem Operate

        public async Task AddFormItem(FormItemCreateDto formItemCreateDto)
        {
            var formItem = Mapper.Map<FormItemCreateDto, FormItem>(formItemCreateDto);
            formItem.Id = Guid.NewGuid();

            await _serviceProvider.DoDapperServiceAsync(DefaultDbConfig, async (unitOfWork) =>
            {
                var formItemRepository = new GuidRepositoryBase<FormItem>(unitOfWork);
                var spriteFormRepository = ConnectionFactory.GetConnectionProvider(DefaultDbConfig.ConnectionType).GetRepository<ISpriteFormRepository>(unitOfWork);

                var formItemHandler = _serviceProvider.GetService<FormItemHandler>();
                var spriteFormHandler = _serviceProvider.GetService<SpriteFormHandler>();

                formItemHandler.SetNext(spriteFormHandler, unitOfWork);
                spriteFormHandler.SetNext(null, unitOfWork);

                await formItemHandler.AddFormItem(formItem, formItemRepository);
                await spriteFormHandler.ChangeItemRowOrCol(formItem.FormId, spriteFormRepository);

                _applicationCode = await spriteFormRepository.GetApplicationCodeAsync(CommonConsts.SpriteFormTableName, formItemCreateDto.FormId);
            });
            CacheSendNotice.SendClearCache($"{CommonConsts.SpriteFormCachePreKey}-{_applicationCode}_{CommonConsts.SpriteFormCacheKey}");
        }

        public async Task UpdateFormItem(FormItemUpdateDto formItemUpdateDto)
        {
            await _serviceProvider.DoDapperServiceAsync(DefaultDbConfig, async (unitOfWork) =>
            {
                var formItemRepository = new GuidRepositoryBase<FormItem>(unitOfWork);
                var spriteFormRepository = ConnectionFactory.GetConnectionProvider(DefaultDbConfig.ConnectionType).GetRepository<ISpriteFormRepository>(unitOfWork);

                var formItem = await formItemRepository.GetAsync(formItemUpdateDto.Id);
                if (formItem == null)
                {
                    throw new SpriteException("未找到FormItem数据信息");
                }
                Mapper.Map(formItemUpdateDto, formItem);

                var formItemHandler = _serviceProvider.GetService<FormItemHandler>();
                var spriteFormHandler = _serviceProvider.GetService<SpriteFormHandler>();

                formItemHandler.SetNext(spriteFormHandler, unitOfWork);
                spriteFormHandler.SetNext(null, unitOfWork);

                await formItemHandler.UpdateFormItem(formItem, formItemRepository);
                await spriteFormHandler.ChangeItemRowOrCol(formItem.FormId, spriteFormRepository);

                _applicationCode = await spriteFormRepository.GetApplicationCodeAsync(CommonConsts.SpriteFormTableName, formItem.FormId);
            });
            CacheSendNotice.SendClearCache($"{CommonConsts.SpriteFormCachePreKey}-{_applicationCode}_{CommonConsts.SpriteFormCacheKey}");
        }

        public async Task DeleteFormItem(Guid id)
        {
            await _serviceProvider.DoDapperServiceAsync(DefaultDbConfig, async (unitOfWork) =>
            {
                var formItemRepository = new GuidRepositoryBase<FormItem>(unitOfWork);
                var spriteFormRepository = ConnectionFactory.GetConnectionProvider(DefaultDbConfig.ConnectionType).GetRepository<ISpriteFormRepository>(unitOfWork);
                var spriteCommonRepository = ConnectionFactory.GetConnectionProvider(DefaultDbConfig.ConnectionType).GetRepository<ISpriteCommonRepository>(unitOfWork);

                var deleteData = await formItemRepository.GetAsync(id);
                if (deleteData == null)
                {
                    throw new SpriteException("未找到FormItem数据信息");
                }

                var formItemHandler = _serviceProvider.GetService<FormItemHandler>();
                var spriteFormHandler = _serviceProvider.GetService<SpriteFormHandler>();

                formItemHandler.SetNext(spriteFormHandler, unitOfWork);
                spriteFormHandler.SetNext(null, unitOfWork);

                await formItemHandler.DeleteFormItem(deleteData, spriteCommonRepository);
                await spriteFormHandler.ChangeItemRowOrCol(deleteData.FormId, spriteFormRepository);

                _applicationCode = await spriteFormRepository.GetApplicationCodeAsync(CommonConsts.SpriteFormTableName, deleteData.FormId);
            });
            CacheSendNotice.SendClearCache($"{CommonConsts.SpriteFormCachePreKey}-{_applicationCode}_{CommonConsts.SpriteFormCacheKey}");
        }

        public async Task<List<FormItem>> GetListFormItemAsync(Guid formId)
        {
            return await _serviceProvider.DoDapperServiceAsync(DefaultDbConfig, async (unitOfWork) =>
            {
                var spriteCommonRepository = ConnectionFactory.GetConnectionProvider(DefaultDbConfig.ConnectionType).GetRepository<ISpriteCommonRepository>(unitOfWork);
                List<QueryWhereModel> queryWhereModels = new List<QueryWhereModel>()
                {
                    new QueryWhereModel()
                    {
                        Field = "FormId",
                        ConditionType = EConditionType.等于,
                        Value = formId
                    }
                };
                var result = await spriteCommonRepository.GetCommonList<FormItem>("FormItems", queryWhereModels);
                return result;
            });
        }

        #endregion

        #region FormRow Operate

        public async Task AddFormRow(FormRowCreateDto formRowCreateDto)
        {
            var formRow = Mapper.Map<FormRowCreateDto, FormRow>(formRowCreateDto);
            formRow.Id = Guid.NewGuid();

            await _serviceProvider.DoDapperServiceAsync(DefaultDbConfig, async (unitOfWork) =>
            {
                var formRowRepository = new GuidRepositoryBase<FormRow>(unitOfWork);
                var spriteFormRepository = ConnectionFactory.GetConnectionProvider(DefaultDbConfig.ConnectionType).GetRepository<ISpriteFormRepository>(unitOfWork);

                var formRowHandler = _serviceProvider.GetService<FormRowHandler>();
                var spriteFormHandler = _serviceProvider.GetService<SpriteFormHandler>();

                formRowHandler.SetNext(spriteFormHandler, unitOfWork);
                spriteFormHandler.SetNext(null, unitOfWork);

                await formRowHandler.AddFormRow(formRow, formRowRepository);
                await spriteFormHandler.ChangeItemRowOrCol(formRow.FormId, spriteFormRepository);

                _applicationCode = await spriteFormRepository.GetApplicationCodeAsync(CommonConsts.SpriteFormTableName, formRowCreateDto.FormId);
            });
            CacheSendNotice.SendClearCache($"{CommonConsts.SpriteFormCachePreKey}-{_applicationCode}_{CommonConsts.SpriteFormCacheKey}");
        }

        public async Task UpdateFormRow(FormRowUpdateDto formRowUpdateDto)
        {
            await _serviceProvider.DoDapperServiceAsync(DefaultDbConfig, async (unitOfWork) =>
            {
                var formRowRepository = new GuidRepositoryBase<FormRow>(unitOfWork);
                var spriteFormRepository = ConnectionFactory.GetConnectionProvider(DefaultDbConfig.ConnectionType).GetRepository<ISpriteFormRepository>(unitOfWork);

                var formRow = await formRowRepository.GetAsync(formRowUpdateDto.Id);
                if (formRow == null)
                {
                    throw new SpriteException("未找到FormRow数据信息");
                }
                Mapper.Map(formRowUpdateDto, formRow);

                var formRowHandler = _serviceProvider.GetService<FormRowHandler>();
                var spriteFormHandler = _serviceProvider.GetService<SpriteFormHandler>();

                formRowHandler.SetNext(spriteFormHandler, unitOfWork);
                spriteFormHandler.SetNext(null, unitOfWork);

                await formRowHandler.UpdateFormRow(formRow, formRowRepository);
                await spriteFormHandler.ChangeItemRowOrCol(formRow.FormId, spriteFormRepository);

                _applicationCode = await spriteFormRepository.GetApplicationCodeAsync(CommonConsts.SpriteFormTableName, formRow.FormId);
            });
            CacheSendNotice.SendClearCache($"{CommonConsts.SpriteFormCachePreKey}-{_applicationCode}_{CommonConsts.SpriteFormCacheKey}");
        }

        public async Task DeleteFormRow(Guid id)
        {
            await _serviceProvider.DoDapperServiceAsync(DefaultDbConfig, async (unitOfWork) =>
            {
                var formRowRepository = new GuidRepositoryBase<FormRow>(unitOfWork);
                var spriteFormRepository = ConnectionFactory.GetConnectionProvider(DefaultDbConfig.ConnectionType).GetRepository<ISpriteFormRepository>(unitOfWork);
                var spriteCommonRepository = ConnectionFactory.GetConnectionProvider(DefaultDbConfig.ConnectionType).GetRepository<ISpriteCommonRepository>(unitOfWork);

                var deleteData = await formRowRepository.GetAsync(id);
                if (deleteData == null)
                {
                    throw new SpriteException("未找到FormRow数据信息");
                }

                var formRowHandler = _serviceProvider.GetService<FormRowHandler>();
                var spriteFormHandler = _serviceProvider.GetService<SpriteFormHandler>();

                formRowHandler.SetNext(spriteFormHandler, unitOfWork);
                spriteFormHandler.SetNext(null, unitOfWork);

                await formRowHandler.DeleteFormRow(deleteData, spriteCommonRepository);
                await spriteFormHandler.ChangeItemRowOrCol(deleteData.FormId, spriteFormRepository);

                _applicationCode = await spriteFormRepository.GetApplicationCodeAsync(CommonConsts.SpriteFormTableName, deleteData.FormId);
            });
            CacheSendNotice.SendClearCache($"{CommonConsts.SpriteFormCachePreKey}-{_applicationCode}_{CommonConsts.SpriteFormCacheKey}");
        }

        public async Task<List<FormRow>> GetListFormRowAsync(Guid formItemId)
        {
            return await _serviceProvider.DoDapperServiceAsync(DefaultDbConfig, async (unitOfWork) =>
            {
                var spriteCommonRepository = ConnectionFactory.GetConnectionProvider(DefaultDbConfig.ConnectionType).GetRepository<ISpriteCommonRepository>(unitOfWork);
                List<QueryWhereModel> queryWhereModels = new List<QueryWhereModel>()
                {
                    new QueryWhereModel()
                    {
                        Field = "FormItemId",
                        ConditionType = EConditionType.等于,
                        Value = formItemId
                    }
                };
                var result = await spriteCommonRepository.GetCommonList<FormRow>("FormRows", queryWhereModels);
                return result;
            });
        }

        #endregion

        #region FormCol Operate

        public async Task AddFormCol(FormColCreateDto formColCreateDto)
        {
            var formCol = Mapper.Map<FormColCreateDto, FormCol>(formColCreateDto);
            formCol.Id = Guid.NewGuid();

            await _serviceProvider.DoDapperServiceAsync(DefaultDbConfig, async (unitOfWork) =>
            {
                var formColRepository = new GuidRepositoryBase<FormCol>(unitOfWork);
                var spriteFormRepository = ConnectionFactory.GetConnectionProvider(DefaultDbConfig.ConnectionType).GetRepository<ISpriteFormRepository>(unitOfWork);

                var formColHandler = _serviceProvider.GetService<FormColHandler>();
                var spriteFormHandler = _serviceProvider.GetService<SpriteFormHandler>();

                formColHandler.SetNext(spriteFormHandler, unitOfWork);
                spriteFormHandler.SetNext(null, unitOfWork);

                await formColHandler.AddFormCol(formCol, formColRepository);
                await spriteFormHandler.ChangeItemRowOrCol(formCol.FormId, spriteFormRepository);

                _applicationCode = await spriteFormRepository.GetApplicationCodeAsync(CommonConsts.SpriteFormTableName, formColCreateDto.FormId);
            });
            CacheSendNotice.SendClearCache($"{CommonConsts.SpriteFormCachePreKey}-{_applicationCode}_{CommonConsts.SpriteFormCacheKey}");
        }

        public async Task UpdateFormCol(FormColUpdateDto formColUpdateDto)
        {
            await _serviceProvider.DoDapperServiceAsync(DefaultDbConfig, async (unitOfWork) =>
            {
                var formColRepository = new GuidRepositoryBase<FormCol>(unitOfWork);
                var spriteFormRepository = ConnectionFactory.GetConnectionProvider(DefaultDbConfig.ConnectionType).GetRepository<ISpriteFormRepository>(unitOfWork);

                var formCol = await formColRepository.GetAsync(formColUpdateDto.Id);
                if (formCol == null)
                {
                    throw new SpriteException("未找到FormCol数据信息");
                }
                Mapper.Map(formColUpdateDto, formCol);

                var formColHandler = _serviceProvider.GetService<FormColHandler>();
                var spriteFormHandler = _serviceProvider.GetService<SpriteFormHandler>();

                formColHandler.SetNext(spriteFormHandler, unitOfWork);
                spriteFormHandler.SetNext(null, unitOfWork);

                await formColHandler.UpdateFormCol(formCol, formColRepository);
                await spriteFormHandler.ChangeItemRowOrCol(formCol.FormId, spriteFormRepository);

                _applicationCode = await spriteFormRepository.GetApplicationCodeAsync(CommonConsts.SpriteFormTableName, formCol.FormId);
            });
            CacheSendNotice.SendClearCache($"{CommonConsts.SpriteFormCachePreKey}-{_applicationCode}_{CommonConsts.SpriteFormCacheKey}");
        }

        public async Task DeleteFormCol(Guid id)
        {
            await _serviceProvider.DoDapperServiceAsync(DefaultDbConfig, async (unitOfWork) =>
            {
                var formColRepository = new GuidRepositoryBase<FormCol>(unitOfWork);
                var spriteFormRepository = ConnectionFactory.GetConnectionProvider(DefaultDbConfig.ConnectionType).GetRepository<ISpriteFormRepository>(unitOfWork);

                var deleteData = await formColRepository.GetAsync(id);
                if (deleteData == null)
                {
                    throw new SpriteException("未找到FormCol数据信息");
                }

                var formColHandler = _serviceProvider.GetService<FormColHandler>();
                var spriteFormHandler = _serviceProvider.GetService<SpriteFormHandler>();

                formColHandler.SetNext(spriteFormHandler, unitOfWork);
                spriteFormHandler.SetNext(null, unitOfWork);

                await formColHandler.DeleteFormCol(deleteData, formColRepository);
                await spriteFormHandler.ChangeItemRowOrCol(deleteData.FormId, spriteFormRepository);

                _applicationCode = await spriteFormRepository.GetApplicationCodeAsync(CommonConsts.SpriteFormTableName, deleteData.FormId);
            });
            CacheSendNotice.SendClearCache($"{CommonConsts.SpriteFormCachePreKey}-{_applicationCode}_{CommonConsts.SpriteFormCacheKey}");
        }

        public async Task<List<FormCol>> GetListFormColAsync(Guid formRowId)
        {
            return await _serviceProvider.DoDapperServiceAsync(DefaultDbConfig, async (unitOfWork) =>
            {
                var spriteCommonRepository = ConnectionFactory.GetConnectionProvider(DefaultDbConfig.ConnectionType).GetRepository<ISpriteCommonRepository>(unitOfWork);
                List<QueryWhereModel> queryWhereModels = new List<QueryWhereModel>()
                {
                    new QueryWhereModel()
                    {
                        Field = "FormRowId",
                        ConditionType = EConditionType.等于,
                        Value = formRowId
                    }
                };
                var result = await spriteCommonRepository.GetCommonList<FormCol>("FormCols", queryWhereModels);
                return result;
            });
        }

        #endregion

        #region Form Template

        // objectNameMap和descriptionMap格式必须为：Org1:Dest1;Org2:Dest2
        public async Task CreateFormFromTemplate(Guid formId, string applicationCode, string objectNameMap, string descriptionMap, string strExcludeCreateFields, string category, int itemRowColCount = 2)
        {
            _applicationCode = applicationCode;
            var excludeCreateFields = new List<string>();
            if (!string.IsNullOrEmpty(strExcludeCreateFields))
            {
                excludeCreateFields = strExcludeCreateFields.Split(new char[] { ';' }).ToList();
            }

            Dictionary<string, string> dictObjectNames = new Dictionary<string, string>();
            var splitObjectNames = objectNameMap.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (var splitObjectName in splitObjectNames)
            {
                var tempObjectNames = splitObjectName.Split(':');
                dictObjectNames.Add(tempObjectNames[0], tempObjectNames[1]);
            }

            Dictionary<string, string> dictDescriptions = new Dictionary<string, string>();
            var splitDescriptions = descriptionMap.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (var splitDescription in splitDescriptions)
            {
                var tempDescriptions = splitDescription.Split(':');
                dictDescriptions.Add(tempDescriptions[0], tempDescriptions[1]);
            }

            var findSpriteForm = await _serviceProvider.DoDapperServiceAsync(DefaultDbConfig, async (unitOfWork) =>
            {
                var spriteFormRepository = new GuidRepositoryBase<SpriteForm>(unitOfWork);
                var dbSpriteForm = await spriteFormRepository.GetAsync(formId);
                if (dbSpriteForm == null)
                {
                    throw new SpriteException("模板信息未找到");
                }
                return dbSpriteForm;
            });

            var formViewVueInfos = new FormViewVueInfos();

            var spriteFormCaches = SpriteFormLocalCache.GetAllDict(findSpriteForm.ApplicationCode);
            var spriteViewCaches = SpriteViewLocalCache.GetAllDict(findSpriteForm.ApplicationCode);

            CalculateFormViewVueInfo(formViewVueInfos, spriteFormCaches, spriteViewCaches, formId, true);

            var formIds = formViewVueInfos.FormDatas.Select(r => r.Id).ToList();
            var viewIds = formViewVueInfos.ViewDatas.Select(r => r.Id).ToList();

            List<SpriteForm> spriteForms = new List<SpriteForm>();
            List<SpriteView> spriteViews = new List<SpriteView>();

            List<Control> formControls = new List<Control>();
            List<Control> viewControls = new List<Control>();
            List<SpriteRule> formSpriteRules = new List<SpriteRule>();
            List<SpriteRule> viewSpriteRules = new List<SpriteRule>();
            List<RuleAction> formRuleActions = new List<RuleAction>();
            List<RuleAction> viewRuleActions = new List<RuleAction>();
            List<WrapInfo> formWrapInfos = new List<WrapInfo>();
            List<WrapInfo> viewWrapInfos = new List<WrapInfo>();

            List<FormItem> formItems = new List<FormItem>();
            List<FormRow> formRows = new List<FormRow>();
            List<FormCol> formCols = new List<FormCol>();

            List<ItemViewRow> itemViewRows = new List<ItemViewRow>();
            List<ItemViewCol> itemViewCols = new List<ItemViewCol>();
            List<ListViewFilter> listViewFilters = new List<ListViewFilter>();
            List<ListViewCustomerColumn> listViewCustomerColumns = new List<ListViewCustomerColumn>();

            #region 查询数据模板数据库相关数据

            await _serviceProvider.DoDapperServiceAsync(DefaultDbConfig, async (unitOfWork) =>
            {
                var spriteCommonRepository = ConnectionFactory.GetConnectionProvider(DefaultDbConfig.ConnectionType).GetRepository<ISpriteCommonRepository>(unitOfWork);
                List<QueryWhereModel> queryBusinessFormWhereModels = new List<QueryWhereModel>()
                {
                    new QueryWhereModel()
                    {
                        Field = "BusinessId",
                        ConditionType = EConditionType.In,
                        Value = JArray.FromObject(formIds)
                    }
                };

                List<QueryWhereModel> queryBusinessViewWhereModels = new List<QueryWhereModel>()
                {
                    new QueryWhereModel()
                    {
                        Field = "BusinessId",
                        ConditionType = EConditionType.In,
                        Value = JArray.FromObject(viewIds)
                    }
                };

                List<QueryWhereModel> queryFormIdWhereModels = new List<QueryWhereModel>()
                {
                    new QueryWhereModel()
                    {
                        Field = "FormId",
                        ConditionType = EConditionType.In,
                        Value = JArray.FromObject(formIds)
                    }
                };

                List<QueryWhereModel> queryViewIdWhereModels = new List<QueryWhereModel>()
                {
                    new QueryWhereModel()
                    {
                        Field = "ViewId",
                        ConditionType = EConditionType.In,
                        Value = JArray.FromObject(viewIds)
                    }
                };

                List<QueryWhereModel> queryIdFormWhereModels = new List<QueryWhereModel>()
                {
                    new QueryWhereModel()
                    {
                        Field = "Id",
                        ConditionType = EConditionType.In,
                        Value = JArray.FromObject(formIds)
                    }
                };

                List<QueryWhereModel> queryIdViewWhereModels = new List<QueryWhereModel>()
                {
                    new QueryWhereModel()
                    {
                        Field = "Id",
                        ConditionType = EConditionType.In,
                        Value = JArray.FromObject(viewIds)
                    }
                };
                spriteForms = await spriteCommonRepository.GetCommonList<SpriteForm>("SpriteForms", queryIdFormWhereModels);
                spriteViews = await spriteCommonRepository.GetCommonList<SpriteView>("SpriteViews", queryIdViewWhereModels);

                formControls = await spriteCommonRepository.GetCommonList<Control>("Controls", queryBusinessFormWhereModels);
                viewControls = await spriteCommonRepository.GetCommonList<Control>("Controls", queryBusinessViewWhereModels);
                formSpriteRules = await spriteCommonRepository.GetCommonList<SpriteRule>("SpriteRules", queryBusinessFormWhereModels);
                viewSpriteRules = await spriteCommonRepository.GetCommonList<SpriteRule>("SpriteRules", queryBusinessViewWhereModels);
                formRuleActions = await spriteCommonRepository.GetCommonList<RuleAction>("RuleActions", queryBusinessFormWhereModels);
                viewRuleActions = await spriteCommonRepository.GetCommonList<RuleAction>("RuleActions", queryBusinessViewWhereModels);
                formWrapInfos = await spriteCommonRepository.GetCommonList<WrapInfo>("WrapInfos", queryBusinessFormWhereModels);
                viewWrapInfos = await spriteCommonRepository.GetCommonList<WrapInfo>("WrapInfos", queryBusinessViewWhereModels);

                formItems = await spriteCommonRepository.GetCommonList<FormItem>("FormItems", queryFormIdWhereModels);
                formRows = await spriteCommonRepository.GetCommonList<FormRow>("FormRows", queryFormIdWhereModels);
                formCols = await spriteCommonRepository.GetCommonList<FormCol>("FormCols", queryFormIdWhereModels);

                //itemViewRows = await spriteCommonRepository.GetCommonList<ItemViewRow>("ItemViewRows", queryViewIdWhereModels);
                //itemViewCols = await spriteCommonRepository.GetCommonList<ItemViewCol>("ItemViewCols", queryViewIdWhereModels);
            });

            #endregion

            #region 替换Id

            foreach (var spriteForm in spriteForms)
            {
                CalculateId(spriteForm.Id);
                CalculateId(spriteForm.Version);

                spriteForm.Id = idMapes[spriteForm.Id];
                spriteForm.Version = idMapes[spriteForm.Version];
                spriteForm.ApplicationCode = applicationCode;
                spriteForm.Name = ReplaceName(dictObjectNames, dictDescriptions, spriteForm.Name);
                spriteForm.Description = ReplaceName(dictObjectNames, dictDescriptions, spriteForm.Description);
                spriteForm.Category = category;
                spriteForm.IsTemplate = false;
            }
            foreach (var spriteView in spriteViews)
            {
                CalculateId(spriteView.Id);
                CalculateId(spriteView.Version);

                spriteView.Id = idMapes[spriteView.Id];
                spriteView.Version = idMapes[spriteView.Version];
                spriteView.ApplicationCode = applicationCode;
                spriteView.Name = ReplaceName(dictObjectNames, dictDescriptions, spriteView.Name);
                spriteView.Description = ReplaceName(dictObjectNames, dictDescriptions, spriteView.Description);
                spriteView.Category = category;
            }

            foreach (var formControl in formControls)
            {
                CalculateId(formControl.Id);
                CalculateId(formControl.BusinessId);

                formControl.Id = idMapes[formControl.Id];
                formControl.BusinessId = idMapes[formControl.BusinessId];
            }
            foreach (var viewControl in viewControls)
            {
                CalculateId(viewControl.Id);
                CalculateId(viewControl.BusinessId);

                viewControl.Id = idMapes[viewControl.Id];
                viewControl.BusinessId = idMapes[viewControl.BusinessId];
            }
            foreach (var formSpriteRule in formSpriteRules)
            {
                CalculateId(formSpriteRule.Id);
                CalculateId(formSpriteRule.BusinessId);
                CalculateId(formSpriteRule.SubFormId);
                CalculateId(formSpriteRule.SubViewId);

                formSpriteRule.Id = idMapes[formSpriteRule.Id];
                formSpriteRule.BusinessId = idMapes[formSpriteRule.BusinessId];
                if (formSpriteRule.SubFormId.HasValue)
                {
                    formSpriteRule.SubFormId = idMapes[formSpriteRule.SubFormId.Value];
                }
                if (formSpriteRule.SubViewId.HasValue)
                {
                    formSpriteRule.SubViewId = idMapes[formSpriteRule.SubViewId.Value];
                }
            }
            foreach (var viewSpriteRule in viewSpriteRules)
            {
                CalculateId(viewSpriteRule.Id);
                CalculateId(viewSpriteRule.BusinessId);
                CalculateId(viewSpriteRule.SubFormId);
                CalculateId(viewSpriteRule.SubViewId);

                viewSpriteRule.Id = idMapes[viewSpriteRule.Id];
                viewSpriteRule.BusinessId = idMapes[viewSpriteRule.BusinessId];
                if (viewSpriteRule.SubFormId.HasValue)
                {
                    viewSpriteRule.SubFormId = idMapes[viewSpriteRule.SubFormId.Value];
                }
                if (viewSpriteRule.SubViewId.HasValue)
                {
                    viewSpriteRule.SubViewId = idMapes[viewSpriteRule.SubViewId.Value];
                }
            }
            foreach (var formRuleAction in formRuleActions)
            {
                CalculateId(formRuleAction.Id);
                CalculateId(formRuleAction.BusinessId);
                CalculateId(formRuleAction.RuleId);
                CalculateId(formRuleAction.SubFormId);
                CalculateId(formRuleAction.SubViewId);

                formRuleAction.Id = idMapes[formRuleAction.Id];
                formRuleAction.BusinessId = idMapes[formRuleAction.BusinessId];
                formRuleAction.RuleId = idMapes[formRuleAction.RuleId];
                if (formRuleAction.SubFormId.HasValue)
                {
                    formRuleAction.SubFormId = idMapes[formRuleAction.SubFormId.Value];
                }
                if (formRuleAction.SubViewId.HasValue)
                {
                    formRuleAction.SubViewId = idMapes[formRuleAction.SubViewId.Value];
                }
            }
            foreach (var viewRuleAction in viewRuleActions)
            {
                CalculateId(viewRuleAction.Id);
                CalculateId(viewRuleAction.BusinessId);
                CalculateId(viewRuleAction.RuleId);
                CalculateId(viewRuleAction.SubFormId);
                CalculateId(viewRuleAction.SubViewId);

                viewRuleAction.Id = idMapes[viewRuleAction.Id];
                viewRuleAction.BusinessId = idMapes[viewRuleAction.BusinessId];
                viewRuleAction.RuleId = idMapes[viewRuleAction.RuleId];
                if (viewRuleAction.SubFormId.HasValue)
                {
                    viewRuleAction.SubFormId = idMapes[viewRuleAction.SubFormId.Value];
                }
                if (viewRuleAction.SubViewId.HasValue)
                {
                    viewRuleAction.SubViewId = idMapes[viewRuleAction.SubViewId.Value];
                }
            }
            foreach (var formWrapInfo in formWrapInfos)
            {
                CalculateId(formWrapInfo.Id);
                CalculateId(formWrapInfo.BusinessId);
                CalculateId(formWrapInfo.ObjId);

                formWrapInfo.Id = idMapes[formWrapInfo.Id];
                formWrapInfo.BusinessId = idMapes[formWrapInfo.BusinessId];
                if (formWrapInfo.ObjId.HasValue)
                {
                    formWrapInfo.ObjId = idMapes[formWrapInfo.ObjId.Value];
                }
            }
            foreach (var viewWrapInfo in viewWrapInfos)
            {
                CalculateId(viewWrapInfo.Id);
                CalculateId(viewWrapInfo.BusinessId);
                CalculateId(viewWrapInfo.ObjId);

                viewWrapInfo.Id = idMapes[viewWrapInfo.Id];
                viewWrapInfo.BusinessId = idMapes[viewWrapInfo.BusinessId];
                if (viewWrapInfo.ObjId.HasValue)
                {
                    viewWrapInfo.ObjId = idMapes[viewWrapInfo.ObjId.Value];
                }
            }

            foreach (var formItem in formItems)
            {
                CalculateId(formItem.Id);
                CalculateId(formItem.FormId);

                formItem.Id = idMapes[formItem.Id];
                formItem.FormId = idMapes[formItem.FormId];
            }
            foreach (var formRow in formRows)
            {
                CalculateId(formRow.Id);
                CalculateId(formRow.FormId);
                CalculateId(formRow.FormItemId);

                formRow.Id = idMapes[formRow.Id];
                formRow.FormId = idMapes[formRow.FormId];
                formRow.FormItemId = idMapes[formRow.FormItemId];
            }
            foreach (var formCol in formCols)
            {
                CalculateId(formCol.Id);
                CalculateId(formCol.FormId);
                CalculateId(formCol.FormRowId);
                CalculateId(formCol.ObjId);

                formCol.Id = idMapes[formCol.Id];
                formCol.FormId = idMapes[formCol.FormId];
                formCol.FormRowId = idMapes[formCol.FormRowId];
                if (formCol.ObjId.HasValue)
                {
                    formCol.ObjId = idMapes[formCol.ObjId.Value];
                }
            }

            foreach (var itemViewRow in itemViewRows)// 重新计算
            {
                CalculateId(itemViewRow.Id);
                CalculateId(itemViewRow.ViewId);

                itemViewRow.Id = idMapes[itemViewRow.Id];
                itemViewRow.ViewId = idMapes[itemViewRow.ViewId];
            }
            foreach (var itemViewCol in itemViewCols) // 重新计算
            {
                CalculateId(itemViewCol.Id);
                CalculateId(itemViewCol.ViewId);
                CalculateId(itemViewCol.ItemViewRowId);
                CalculateId(itemViewCol.ObjId);

                itemViewCol.Id = idMapes[itemViewCol.Id];
                itemViewCol.ViewId = idMapes[itemViewCol.ViewId];
                itemViewCol.ItemViewRowId = idMapes[itemViewCol.ItemViewRowId];
                if (itemViewCol.ObjId.HasValue)
                {
                    itemViewCol.ObjId = idMapes[itemViewCol.ObjId.Value];
                }
            }

            #endregion

            #region 重新计算与Object相关表单和视图数据

            var itemViews = spriteViews.Where(r => r.ViewType == EViewType.ItemView).ToList();
            if (itemViews.Count > 0)
            {
                ItemViewRow currentItemViewRow = null;
                foreach (var itemView in itemViews)
                {
                    var oldObjectName = itemView.ObjectName;
                    if (!dictObjectNames.ContainsKey(oldObjectName))
                    {
                        throw new SpriteException($"未找到{oldObjectName}对象Map信息，请传递");
                    }
                    var spriteObject = SpriteObjectLocalCache.GetAll(applicationCode).FirstOrDefault(r => r.Name == dictObjectNames[oldObjectName]);
                    if (spriteObject == null)
                    {
                        throw new SpriteException($"未找到{dictObjectNames[oldObjectName]}数据库对象名称");
                    }

                    for (var i = 0; i < spriteObject.ObjectPropertyDtos.Count; i++) // 固定两行
                    {
                        var propertyDto = spriteObject.ObjectPropertyDtos[i];
                        if (i % itemRowColCount == 0)
                        {
                            currentItemViewRow = new ItemViewRow()
                            {
                                Id = Guid.NewGuid(),
                                ViewId = itemView.Id,
                                Children = new List<ItemViewCol>(),
                                Order = (i / itemRowColCount).ToString("00")
                            };
                            itemViewRows.Add(currentItemViewRow);
                        }
                        var componentName = string.IsNullOrEmpty(propertyDto.DefaultControl) ? "col-form-common" : propertyDto.DefaultControl;
                        var controlSettings = string.IsNullOrEmpty(propertyDto.DefaultControlSettings) ? "" : propertyDto.DefaultControlSettings;
                        if (!string.IsNullOrEmpty(propertyDto.Dict))
                        {
                            componentName = "col-form-dict";
                            controlSettings = $"{{'placeholder':'请选择{propertyDto.Description}信息', 'dict':'{propertyDto.Dict}','componentName':'a-select'}}";
                        }
                        ItemViewCol itemViewCol = new ItemViewCol()
                        {
                            Id = Guid.NewGuid(),
                            ViewId = itemView.Id,
                            ItemViewRowId = currentItemViewRow.Id,
                            ColType = EColType.Control,
                            LabelValue = propertyDto.Description,
                            Order = (i % itemRowColCount).ToString("00"),
                            FieldIds = propertyDto.Name.ToCamelCase(),
                            PropertySettings = @"{'span':#span#}".Replace("#span#", (24 / itemRowColCount).ToString()),
                            ComponentName = componentName,
                            ControlSettings = controlSettings,
                            Description = propertyDto.Description
                        };
                        // todo 详细验证每种类型
                        // todo 日期范围
                        JArray validateArray = new JArray();
                        if (!string.IsNullOrEmpty(propertyDto.DefaultValidate))
                        {
                            validateArray = JsonConvert.DeserializeObject<JArray>(propertyDto.DefaultValidate);
                        }
                        else
                        {
                            switch (propertyDto.FieldType)
                            {
                                case EFieldType.Int:
                                    validateArray.Add(JsonConvert.DeserializeObject("{'customerVal':'Integer12','trigger':'blur'}"));
                                    break;
                                case EFieldType.Decimal:
                                    validateArray.Add(JsonConvert.DeserializeObject("{'customerVal':'Double','trigger':'blur'}"));
                                    break;
                                case EFieldType.Float:
                                    validateArray.Add(JsonConvert.DeserializeObject("{'customerVal':'Double','trigger':'blur'}"));
                                    break;
                            }
                        }
                        if (propertyDto.FieldType == EFieldType.String && string.IsNullOrEmpty(propertyDto.Dict))
                        {
                            validateArray.Add(JsonConvert.DeserializeObject($"{{'max':20,'message':'{propertyDto.Description}不能大于{propertyDto.Length}个字符','trigger':'blur'}}"));
                        }
                        if (propertyDto.IsRequired)
                        {
                            validateArray.Add(JsonConvert.DeserializeObject("{'required':true,'message':'请填写此项数据','trigger':'blur'}"));
                        }
                        if (validateArray.Count > 0)
                        {
                            itemViewCol.ValidateRuleJson = validateArray.ToString();
                        }
                        if (string.IsNullOrEmpty(propertyDto.DefaultControlSettings) && string.IsNullOrEmpty(propertyDto.Dict))
                        {
                            switch (propertyDto.FieldType)
                            {
                                case EFieldType.String:
                                    itemViewCol.ControlSettings = $"{{'placeholder':'请输入{propertyDto.Description}','componentName':'a-input'}}";
                                    break;
                                case EFieldType.Int:
                                    itemViewCol.ControlSettings = $"{{'placeholder':'请输入{propertyDto.Description}','componentName':'a-input'}}";
                                    break;
                                case EFieldType.Bool:
                                    itemViewCol.ControlSettings = $"{{'placeholder':'请输入{propertyDto.Description}','componentName':'a-switch'}}";
                                    break;
                                case EFieldType.Date:
                                    itemViewCol.ControlSettings = $"{{'placeholder':'请输入{propertyDto.Description}','componentName':'a-date-picker'}}";
                                    break;
                                case EFieldType.DateTime:
                                    itemViewCol.ControlSettings = $"{{'placeholder':'请输入{propertyDto.Description}','componentName':'a-date-picker'}}";
                                    break;
                                case EFieldType.Text:
                                    itemViewCol.ControlSettings = $"{{'placeholder':'请输入{propertyDto.Description}','componentName':'a-textarea'}}";
                                    break;
                                case EFieldType.Decimal:
                                    itemViewCol.ControlSettings = $"{{'placeholder':'请输入{propertyDto.Description}','componentName':'a-input'}}";
                                    break;
                                case EFieldType.Float:
                                    itemViewCol.ControlSettings = $"{{'placeholder':'请输入{propertyDto.Description}','componentName':'a-input'}}";
                                    break;
                                default:
                                    itemViewCol.ControlSettings = $"{{'placeholder':'请输入{propertyDto.Description}','componentName':'a-input'}}";
                                    break;
                            }
                        }
                        itemViewCols.Add(itemViewCol);
                        (currentItemViewRow.Children as List<ItemViewCol>).Add(itemViewCol);
                    }
                }
            }

            var listViews = spriteViews.Where(r => r.ViewType == EViewType.ListView || r.ViewType == EViewType.ListLocalView).ToList();
            foreach (var listView in listViews)
            {
                if (string.IsNullOrEmpty(listView.ObjectName))
                {
                    throw new SpriteException("未设置模板视图Object信息");
                }
                if (listView.ObjectName.Contains(';'))
                {
                    Dictionary<string, SpriteObjectDto> dictAliasObjects = GetDictAliasSpriteObjectDto(listView.ObjectName);

                    Func<ObjectPropertyDto, bool> func = (r) =>
                    {
                        return r.FieldType == EFieldType.String || r.FieldType == EFieldType.Date || r.FieldType == EFieldType.DateTime || r.FieldType == EFieldType.Text;
                    };
                    Func<ObjectPropertyDto, bool> notFunc = (r) =>
                    {
                        return !(r.FieldType == EFieldType.String || r.FieldType == EFieldType.Date || r.FieldType == EFieldType.DateTime || r.FieldType == EFieldType.Text);
                    };

                    List<TempPropertyDtoAliasInfo> tempNormalPropertyDtoAliasInfos = new List<TempPropertyDtoAliasInfo>();
                    List<TempPropertyDtoAliasInfo> tempNormalProper2PropertyDtoAliasInfos = new List<TempPropertyDtoAliasInfo>();

                    bool isWorkflow = false;
                    foreach (var dictAliasObject in dictAliasObjects)
                    {
                        if (dictAliasObject.Value.IsWorkflow)
                        {
                            TryAddNormalFilter(new ObjectPropertyDto()
                            {
                                Name = "FlowStartTime",
                                Description = "发起时间",
                                FieldType = EFieldType.DateTime
                            }, 0, listView.Id, listViewFilters, $"_{dictAliasObject.Key}");
                            isWorkflow = true;
                        }

                        var findNormalProperties = dictAliasObject.Value.ObjectPropertyDtos.Where(r => !excludeCreateFields.Exists(t => t == r.Name)).Where(func).ToList();
                        foreach (var findNormalProperty in findNormalProperties)
                        {
                            tempNormalPropertyDtoAliasInfos.Add(new TempPropertyDtoAliasInfo()
                            {
                                ObjectPropertyDto = findNormalProperty,
                                Alias = dictAliasObject.Key
                            });
                        }

                        var findNormal2Properties = dictAliasObject.Value.ObjectPropertyDtos.Where(r => !excludeCreateFields.Exists(t => t == r.Name)).Where(notFunc).ToList();
                        foreach (var findNormal2Property in findNormal2Properties)
                        {
                            tempNormalProper2PropertyDtoAliasInfos.Add(new TempPropertyDtoAliasInfo()
                            {
                                ObjectPropertyDto = findNormal2Property,
                                Alias = dictAliasObject.Key
                            });
                        }
                    }

                    for (var i = 0; i < tempNormalPropertyDtoAliasInfos.Count; i++)
                    {
                        if (i < (isWorkflow ? 4 : 5))
                        {
                            TryAddNormalFilter(tempNormalPropertyDtoAliasInfos[i].ObjectPropertyDto, i + 1, listView.Id, listViewFilters, $"_{tempNormalPropertyDtoAliasInfos[i].Alias}");
                        }
                        else
                        {
                            TryAddHightFilter(tempNormalPropertyDtoAliasInfos[i].ObjectPropertyDto, i + 1, listView.Id, listViewFilters, $"_{tempNormalPropertyDtoAliasInfos[i].Alias}");
                        }
                    }
                    for (var i = 0; i < tempNormalProper2PropertyDtoAliasInfos.Count; i++)
                    {
                        TryAddHightFilter(tempNormalProper2PropertyDtoAliasInfos[i].ObjectPropertyDto, i + 1, listView.Id, listViewFilters, $"_{tempNormalProper2PropertyDtoAliasInfos[i].Alias}");
                    }
                }
                else
                {
                    bool isWorkflow = false;
                    var oldObjectName = listView.ObjectName;
                    if (!dictObjectNames.ContainsKey(oldObjectName))
                    {
                        throw new SpriteException($"未找到{oldObjectName}对象Map信息，请传递");
                    }
                    var spriteObject = SpriteObjectLocalCache.GetAll(applicationCode).FirstOrDefault(r => r.Name == dictObjectNames[oldObjectName]);
                    if (spriteObject == null)
                    {
                        throw new SpriteException($"未找到{dictObjectNames[oldObjectName]}数据库对象名称");
                    }

                    Func<ObjectPropertyDto, bool> func = (r) =>
                    {
                        return r.FieldType == EFieldType.String || r.FieldType == EFieldType.Date || r.FieldType == EFieldType.DateTime || r.FieldType == EFieldType.Text;
                    };
                    Func<ObjectPropertyDto, bool> notFunc = (r) =>
                    {
                        return !(r.FieldType == EFieldType.String || r.FieldType == EFieldType.Date || r.FieldType == EFieldType.DateTime || r.FieldType == EFieldType.Text);
                    };
                    var normalProperties = spriteObject.ObjectPropertyDtos.Where(func).ToList();
                    if (spriteObject.IsWorkflow)
                    {
                        TryAddNormalFilter(new ObjectPropertyDto()
                        {
                            Name = "FlowStartTime",
                            Description = "发起时间",
                            FieldType = EFieldType.DateTime
                        }, 0, listView.Id, listViewFilters);
                        isWorkflow = true;
                    }
                    for (var i = 0; i < normalProperties.Count; i++)
                    {
                        if (i < (isWorkflow ? 4 : 5))
                        {
                            TryAddNormalFilter(normalProperties[i], i + 1, listView.Id, listViewFilters);
                        }
                        else
                        {
                            TryAddHightFilter(normalProperties[i], i + 1, listView.Id, listViewFilters);
                        }
                    }
                    var normal2Properties = spriteObject.ObjectPropertyDtos.Where(notFunc).ToList();
                    for (var i = 0; i < normal2Properties.Count; i++)
                    {
                        TryAddHightFilter(normal2Properties[i], i + 1, listView.Id, listViewFilters);
                    }
                }
            }

            #endregion

            #region 重新计算spriteObject相关表单和视图

            foreach (var idMape in idMapes)
            {
                var strOldGuid = idMape.Key.ToString();
                var strNewGuid = idMape.Value.ToString();
                foreach (var formCol in formCols)
                {
                    formCol.WrapConfigs = ReplaceGuid(dictObjectNames, strOldGuid, strNewGuid, formCol.WrapConfigs);
                    formCol.Express = ReplaceGuid(dictObjectNames, strOldGuid, strNewGuid, formCol.Express);
                    formCol.ControlSettings = ReplaceGuid(dictObjectNames, strOldGuid, strNewGuid, formCol.ControlSettings);
                    formCol.PropertySettings = ReplaceGuid(dictObjectNames, strOldGuid, strNewGuid, formCol.PropertySettings);
                }
                foreach (var formRow in formRows)
                {
                    formRow.PropertySettings = ReplaceGuid(dictObjectNames, strOldGuid, strNewGuid, formRow.PropertySettings);
                }
                foreach (var formItem in formItems)
                {
                    formItem.PropertySettings = ReplaceGuid(dictObjectNames, strOldGuid, strNewGuid, formItem.PropertySettings);
                }
                foreach (var viewWrapInfo in viewWrapInfos)
                {
                    viewWrapInfo.WrapConfigs = ReplaceGuid(dictObjectNames, strOldGuid, strNewGuid, viewWrapInfo.WrapConfigs);
                }
                foreach (var formWrapInfo in formWrapInfos)
                {
                    formWrapInfo.WrapConfigs = ReplaceGuid(dictObjectNames, strOldGuid, strNewGuid, formWrapInfo.WrapConfigs);
                }
                foreach (var viewRuleAction in viewRuleActions)
                {
                    viewRuleAction.ObjId = ReplaceGuid(dictObjectNames, strOldGuid, strNewGuid, viewRuleAction.ObjId);
                    viewRuleAction.ActionConfig = ReplaceGuid(dictObjectNames, strOldGuid, strNewGuid, viewRuleAction.ActionConfig);
                }
                foreach (var formRuleAction in formRuleActions)
                {
                    formRuleAction.ObjId = ReplaceGuid(dictObjectNames, strOldGuid, strNewGuid, formRuleAction.ObjId);
                    formRuleAction.ActionConfig = ReplaceGuid(dictObjectNames, strOldGuid, strNewGuid, formRuleAction.ActionConfig);
                }
                foreach (var viewSpriteRule in viewSpriteRules)
                {
                    viewSpriteRule.ObjId = ReplaceGuid(dictObjectNames, strOldGuid, strNewGuid, viewSpriteRule.ObjId);
                }
                foreach (var formSpriteRule in formSpriteRules)
                {
                    formSpriteRule.ObjId = ReplaceGuid(dictObjectNames, strOldGuid, strNewGuid, formSpriteRule.ObjId);
                }
                foreach (var viewControl in viewControls)
                {
                    viewControl.ControlSettings = ReplaceGuid(dictObjectNames, strOldGuid, strNewGuid, viewControl.ControlSettings);
                    var jobjectControlProperty = JsonConvert.DeserializeObject(viewControl.ControlSettings) as JObject;
                    if (jobjectControlProperty.ContainsKey("action"))
                    {
                        jobjectControlProperty.Remove("action");
                        viewControl.ControlSettings = JsonConvert.SerializeObject(jobjectControlProperty, new JsonSerializerSettings { ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver() });
                    }
                }
                foreach (var formControl in formControls)
                {
                    formControl.ControlSettings = ReplaceGuid(dictObjectNames, strOldGuid, strNewGuid, formControl.ControlSettings);
                    var jobjectControlProperty = JsonConvert.DeserializeObject(formControl.ControlSettings) as JObject;
                    if (jobjectControlProperty.ContainsKey("action"))
                    {
                        jobjectControlProperty.Remove("action");
                        formControl.ControlSettings = JsonConvert.SerializeObject(jobjectControlProperty, new JsonSerializerSettings { ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver() });
                    }
                }
                foreach (var spriteForm in spriteForms)
                {
                    spriteForm.PropertySettings = ReplaceGuid(dictObjectNames, strOldGuid, strNewGuid, spriteForm.PropertySettings);
                    spriteForm.Rules = ReplaceGuid(dictObjectNames, strOldGuid, strNewGuid, spriteForm.Rules);
                    spriteForm.WrapInfos = ReplaceGuid(dictObjectNames, strOldGuid, strNewGuid, spriteForm.WrapInfos);
                    spriteForm.Controls = ReplaceGuid(dictObjectNames, strOldGuid, strNewGuid, spriteForm.Controls);
                    spriteForm.FormItems = ReplaceGuid(dictObjectNames, strOldGuid, strNewGuid, spriteForm.FormItems);
                    spriteForm.MenuWrapConfigs = ReplaceGuid(dictObjectNames, strOldGuid, strNewGuid, spriteForm.MenuWrapConfigs);
                }
                foreach (var spriteView in spriteViews)
                {
                    spriteView.PropertySettings = ReplaceGuid(dictObjectNames, strOldGuid, strNewGuid, spriteView.PropertySettings);
                    spriteView.Rules = ReplaceGuid(dictObjectNames, strOldGuid, strNewGuid, spriteView.Rules);
                    spriteView.WrapInfos = ReplaceGuid(dictObjectNames, strOldGuid, strNewGuid, spriteView.WrapInfos);
                    spriteView.Controls = ReplaceGuid(dictObjectNames, strOldGuid, strNewGuid, spriteView.Controls);
                }
            }

            foreach (var spriteView in spriteViews)
            {
                switch (spriteView.ViewType)
                {
                    case EViewType.ItemView:
                        var findItemViewRows = itemViewRows.Where(r => r.ViewId == spriteView.Id).ToList();
                        if (findItemViewRows.Count > 0)
                        {
                            spriteView.Extension1s = JsonConvert.SerializeObject(findItemViewRows, new JsonSerializerSettings { ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver() });
                        }
                        break;
                    case EViewType.ListLocalView:
                    case EViewType.ListView:
                        var findListViewFilters = listViewFilters.Where(r => r.ViewId == spriteView.Id).ToList();
                        if (findListViewFilters.Count > 0)
                        {
                            spriteView.Extension1s = JsonConvert.SerializeObject(findListViewFilters, new JsonSerializerSettings { ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver() });
                        }

                        spriteView.Extension2s = null;

                        var jobjectViewProperty = JsonConvert.DeserializeObject(spriteView.PropertySettings) as JObject;

                        if (spriteView.ObjectName.Contains(';'))
                        {
                            Dictionary<string, SpriteObjectDto> dictAliasObjects = GetDictAliasSpriteObjectDto(spriteView.ObjectName);
                            List<TempPropertyDtoAliasInfo> tempPropertyDtoAliasInfos = new List<TempPropertyDtoAliasInfo>();

                            foreach (var dictAliasObject in dictAliasObjects)
                            {
                                var findProperties = dictAliasObject.Value.ObjectPropertyDtos.Where(r => !excludeCreateFields.Exists(t => t == r.Name)).ToList();
                                foreach (var findNormalProperty in findProperties)
                                {
                                    tempPropertyDtoAliasInfos.Add(new TempPropertyDtoAliasInfo()
                                    {
                                        ObjectPropertyDto = findNormalProperty,
                                        Alias = dictAliasObject.Key
                                    });
                                }
                            }

                            if (jobjectViewProperty.ContainsKey("uniqKey"))
                            {
                                jobjectViewProperty.Remove("uniqKey");
                                spriteView.PropertySettings = JsonConvert.SerializeObject(jobjectViewProperty, new JsonSerializerSettings { ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver() });
                            }

                            CalculateListViewInfo(tempPropertyDtoAliasInfos, spriteView, listViewCustomerColumns, jobjectViewProperty, dictObjectNames, dictDescriptions);
                        }
                        else
                        {
                            var oldObjectName = spriteView.ObjectName;
                            var spriteObject = SpriteObjectLocalCache.GetAll(applicationCode).FirstOrDefault(r => r.Name == dictObjectNames[oldObjectName]);

                            var tempPropertyDtoAliasInfos = new List<TempPropertyDtoAliasInfo>();
                            var findProperties = spriteObject.ObjectPropertyDtos.Where(r => !excludeCreateFields.Exists(t => t == r.Name)).ToList();
                            foreach (var tempObjectPropertyDto in findProperties)
                            {

                                tempPropertyDtoAliasInfos.Add(new TempPropertyDtoAliasInfo()
                                {
                                    ObjectPropertyDto = tempObjectPropertyDto
                                });
                            }

                            if (jobjectViewProperty.ContainsKey("uniqKey"))
                            {
                                jobjectViewProperty.Remove("uniqKey");
                                if (!string.IsNullOrEmpty(spriteObject.UnionIndex))
                                {
                                    jobjectViewProperty.Add("uniqKey", spriteObject.UnionIndex);
                                }
                                else
                                {
                                    var firstUniqPropertyDto = spriteObject.ObjectPropertyDtos.FirstOrDefault(r => r.IsUnique);
                                    if (firstUniqPropertyDto != null)
                                    {
                                        jobjectViewProperty.Add("uniqKey", firstUniqPropertyDto.Name);
                                    }
                                }
                                spriteView.PropertySettings = JsonConvert.SerializeObject(jobjectViewProperty, new JsonSerializerSettings { ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver() });
                            }

                            CalculateListViewInfo(tempPropertyDtoAliasInfos, spriteView, listViewCustomerColumns, jobjectViewProperty, dictObjectNames, dictDescriptions);
                        }
                        break;
                    case EViewType.TreeView:
                        break;
                }
            }

            #endregion

            foreach (var spriteView in spriteViews)
            {
                spriteView.ObjectName = ReplaceName(dictObjectNames, dictDescriptions, spriteView.ObjectName);
            }

            await _serviceProvider.DoDapperServiceAsync(DefaultDbConfig, async (unitOfWork) =>
            {
                var spriteFormRepository = new GuidRepositoryBase<SpriteForm>(unitOfWork);
                var spriteViewRepository = new GuidRepositoryBase<SpriteView>(unitOfWork);
                var controlRepository = new GuidRepositoryBase<Control>(unitOfWork);
                var spriteRuleRepository = new GuidRepositoryBase<SpriteRule>(unitOfWork);
                var ruleActionRepository = new GuidRepositoryBase<RuleAction>(unitOfWork);
                var wrapInfoRepository = new GuidRepositoryBase<WrapInfo>(unitOfWork);
                var formItemRepository = new GuidRepositoryBase<FormItem>(unitOfWork);
                var formRowRepository = new GuidRepositoryBase<FormRow>(unitOfWork);
                var formColRepository = new GuidRepositoryBase<FormCol>(unitOfWork);
                var itemViewRowRepository = new GuidRepositoryBase<ItemViewRow>(unitOfWork);
                var itemViewColRepository = new GuidRepositoryBase<ItemViewCol>(unitOfWork);
                var listViewFilterRepository = new GuidRepositoryBase<ListViewFilter>(unitOfWork);
                var listViewCustomerColumnRepository = new GuidRepositoryBase<ListViewCustomerColumn>(unitOfWork);

                await spriteFormRepository.InsertAsync(spriteForms);
                await spriteViewRepository.InsertAsync(spriteViews);
                await controlRepository.InsertAsync(formControls);
                await controlRepository.InsertAsync(viewControls);
                await spriteRuleRepository.InsertAsync(formSpriteRules);
                await spriteRuleRepository.InsertAsync(viewSpriteRules);
                await ruleActionRepository.InsertAsync(formRuleActions);
                await ruleActionRepository.InsertAsync(viewRuleActions);
                await wrapInfoRepository.InsertAsync(formWrapInfos);
                await wrapInfoRepository.InsertAsync(viewWrapInfos);

                await formItemRepository.InsertAsync(formItems);
                await formRowRepository.InsertAsync(formRows);
                await formColRepository.InsertAsync(formCols);
                await itemViewRowRepository.InsertAsync(itemViewRows);
                await itemViewColRepository.InsertAsync(itemViewCols);
                await listViewFilterRepository.InsertAsync(listViewFilters);
                if (listViewCustomerColumns.Count > 0)
                {
                    await listViewCustomerColumnRepository.InsertAsync(listViewCustomerColumns);
                }
            });

            CacheSendNotice.SendClearCache($"{CommonConsts.SpriteFormCachePreKey}-{applicationCode}_{CommonConsts.SpriteFormCacheKey}");
            CacheSendNotice.SendClearCache($"{CommonConsts.SpriteFormCachePreKey}-{applicationCode}_{CommonConsts.SpriteViewCacheKey}");
        }

        private void CalculateListViewInfo(List<TempPropertyDtoAliasInfo> tempPropertyDtoAliasInfos, SpriteView spriteView, List<ListViewCustomerColumn> listViewCustomerColumns, JObject jobjectViewProperty, Dictionary<string, string> dictObjectNames, Dictionary<string, string> dictDescriptions)
        {
            bool isWorkflow = spriteView.PropertySettings.Contains("isWorkflow");
            if(isWorkflow)
            {
                JObject tempDictObject = new JObject();
                tempDictObject.Add(new JProperty("dict", "instanceStatus"));
                listViewCustomerColumns.Add(new ListViewCustomerColumn()
                {
                    Id = Guid.NewGuid(),
                    DataIndex = "flow_Status",
                    ViewId = spriteView.Id,
                    ComponentName = "col-tbl-icon",
                    ControlSettings = tempDictObject.ToString(),
                });
            }

            foreach (var tempPropertyDtoAliasInfo in tempPropertyDtoAliasInfos)
            {
                var objectPropertyDto = tempPropertyDtoAliasInfo.ObjectPropertyDto;
                var alias = string.IsNullOrEmpty(tempPropertyDtoAliasInfo.Alias) ? "" : $"_{tempPropertyDtoAliasInfo.Alias}";
                if (!string.IsNullOrEmpty(objectPropertyDto.Dict))
                {
                    JObject tempDictObject = new JObject();
                    tempDictObject.Add(new JProperty("dict", objectPropertyDto.Dict));
                    listViewCustomerColumns.Add(new ListViewCustomerColumn()
                    {
                        Id = Guid.NewGuid(),
                        DataIndex = objectPropertyDto.Name.ToCamelCase() + alias,
                        ViewId = spriteView.Id,
                        ComponentName = "col-tbl-icon",
                        ControlSettings = tempDictObject.ToString(),
                    });
                }
                else
                {
                    switch (objectPropertyDto.FieldType)
                    {
                        case EFieldType.Bool:
                            listViewCustomerColumns.Add(new ListViewCustomerColumn()
                            {
                                Id = Guid.NewGuid(),
                                DataIndex = objectPropertyDto.Name.ToCamelCase() + alias,
                                ViewId = spriteView.Id,
                                ComponentName = "col-tbl-text",
                                ControlSettings = "{\"eval_render\":\"text\"}",
                            });
                            break;
                        case EFieldType.Date:
                            listViewCustomerColumns.Add(new ListViewCustomerColumn()
                            {
                                Id = Guid.NewGuid(),
                                DataIndex = objectPropertyDto.Name.ToCamelCase() + alias,
                                ViewId = spriteView.Id,
                                ComponentName = "col-tbl-text",
                                ControlSettings = spriteView.ViewType == EViewType.ListLocalView ? "{\"eval_render\":\"text.format('YYYY-MM-DD')\"}" : "{\"eval_render\":\"text.substring(0, 10)\"}",
                            });
                            break;
                        case EFieldType.DateTime:
                            listViewCustomerColumns.Add(new ListViewCustomerColumn()
                            {
                                Id = Guid.NewGuid(),
                                DataIndex = objectPropertyDto.Name.ToCamelCase() + alias,
                                ViewId = spriteView.Id,
                                ComponentName = "col-tbl-text",
                                ControlSettings = spriteView.ViewType == EViewType.ListLocalView ? "{\"eval_render\":\"text.format('YYYY-MM-DD HH:mm:ss')\"}" : "{\"eval_render\":\"text.substring(0, 19).replace('T', ' ')\"}",
                            });
                            break;
                    }
                }
            }

            if (listViewCustomerColumns.Count > 0)
            {
                spriteView.Extension2s = JsonConvert.SerializeObject(listViewCustomerColumns, new JsonSerializerSettings { ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver() });
            }

            if (jobjectViewProperty.ContainsKey("columns"))
            {
                JArray arrayViewColumns = new JArray();
                foreach (var tempPropertyDtoAliasInfo in tempPropertyDtoAliasInfos)
                {
                    var objectPropertyDto = tempPropertyDtoAliasInfo.ObjectPropertyDto;
                    var alias = string.IsNullOrEmpty(tempPropertyDtoAliasInfo.Alias) ? "" : $"_{tempPropertyDtoAliasInfo.Alias}";
                    JObject tempObjListViewColumn = new JObject();
                    tempObjListViewColumn.Add(new JProperty("align", "center"));
                    tempObjListViewColumn.Add(new JProperty("dataIndex", objectPropertyDto.Name.ToCamelCase() + alias));
                    tempObjListViewColumn.Add(new JProperty("title", objectPropertyDto.Description));
                    if(objectPropertyDto.FieldType == EFieldType.Text || (objectPropertyDto.FieldType == EFieldType.String && objectPropertyDto.Length > 100))
                    {
                        tempObjListViewColumn.Add(new JProperty("ellipsis", true));
                    }
                    if (!string.IsNullOrEmpty(objectPropertyDto.Dict))
                    {
                        tempObjListViewColumn.Add(new JProperty("scopedSlots", JObject.FromObject(new CustomerRender() { customRender = objectPropertyDto.Name.ToCamelCase() + alias })));
                    }
                    else
                    {
                        switch (objectPropertyDto.FieldType)
                        {
                            case EFieldType.Bool:
                            case EFieldType.Date:
                            case EFieldType.DateTime:
                                tempObjListViewColumn.Add(new JProperty("scopedSlots", JObject.FromObject(new CustomerRender() { customRender = objectPropertyDto.Name.ToCamelCase() + alias })));
                                break;
                        }
                    }

                    if(objectPropertyDto.FieldType != EFieldType.AutoGuid && objectPropertyDto.FieldType != EFieldType.AutoNumber && objectPropertyDto.FieldType != EFieldType.Text && objectPropertyDto.FieldType != EFieldType.Guid)
                    {
                        tempObjListViewColumn.Add(new JProperty("sorter", true));
                    }

                    arrayViewColumns.Add(tempObjListViewColumn);
                }
                if(isWorkflow) // 添加流程字段
                {
                    JObject tempInstanceNameListViewColumn = new JObject();
                    tempInstanceNameListViewColumn.Add(new JProperty("align", "center"));
                    tempInstanceNameListViewColumn.Add(new JProperty("dataIndex", "flow_InstanceName"));
                    tempInstanceNameListViewColumn.Add(new JProperty("title", "流程名称"));
                    tempInstanceNameListViewColumn.Add(new JProperty("width", 260));
                    tempInstanceNameListViewColumn.Add(new JProperty("ellipsis", true));
                    arrayViewColumns.Add(tempInstanceNameListViewColumn);

                    JObject tempCurrentActivitiesListViewColumn = new JObject();
                    tempCurrentActivitiesListViewColumn.Add(new JProperty("align", "center"));
                    tempCurrentActivitiesListViewColumn.Add(new JProperty("dataIndex", "flow_CurrentActivities"));
                    tempCurrentActivitiesListViewColumn.Add(new JProperty("title", "当前活动"));
                    tempCurrentActivitiesListViewColumn.Add(new JProperty("ellipsis", true));
                    arrayViewColumns.Add(tempCurrentActivitiesListViewColumn);

                    JObject tempStatusListViewColumn = new JObject();
                    tempStatusListViewColumn.Add(new JProperty("align", "center"));
                    tempStatusListViewColumn.Add(new JProperty("dataIndex", "flow_Status"));
                    tempStatusListViewColumn.Add(new JProperty("width", 80));
                    tempStatusListViewColumn.Add(new JProperty("title", "流程状态"));
                    tempStatusListViewColumn.Add(new JProperty("scopedSlots", JObject.FromObject(new CustomerRender() { customRender = "flow_Status" })));
                    arrayViewColumns.Add(tempStatusListViewColumn);
                }

                jobjectViewProperty.Remove("columns");
                jobjectViewProperty.Add("columns", arrayViewColumns);
                spriteView.PropertySettings = JsonConvert.SerializeObject(jobjectViewProperty, new JsonSerializerSettings { ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver() });
            }
            if (jobjectViewProperty.ContainsKey("excelTemplate"))
            {
                JArray arrayListViewExcel = new JArray();
                foreach (var tempPropertyDtoAliasInfo in tempPropertyDtoAliasInfos)
                {
                    var objectPropertyDto = tempPropertyDtoAliasInfo.ObjectPropertyDto;
                    var alias = string.IsNullOrEmpty(tempPropertyDtoAliasInfo.Alias) ? "" : $"_{tempPropertyDtoAliasInfo.Alias}";
                    JObject tempObjListViewExcel = new JObject();
                    tempObjListViewExcel.Add(new JProperty("name", objectPropertyDto.Description));
                    tempObjListViewExcel.Add(new JProperty("field", objectPropertyDto.Name.ToCamelCase() + alias));
                    tempObjListViewExcel.Add(new JProperty("fieldType", GetExcelFieldType(objectPropertyDto.FieldType)));
                    if (objectPropertyDto.IsRequired)
                    {
                        tempObjListViewExcel.Add(new JProperty("isRequred", objectPropertyDto.IsRequired));
                    }
                    if (!string.IsNullOrEmpty(objectPropertyDto.Dict))
                    {
                        tempObjListViewExcel.Add(new JProperty("validateType", EExcelValidateType.Dict));
                    }
                    else
                    {
                        if (!string.IsNullOrEmpty(objectPropertyDto.DefaultValidate))
                        {
                            tempObjListViewExcel.Add(new JProperty("validateType", EExcelValidateType.Regular));
                            tempObjListViewExcel.Add(new JProperty("validateValue", objectPropertyDto.DefaultValidate));
                        }
                        else
                        {
                            tempObjListViewExcel.Add(new JProperty("validateType", GetNormalExcelValidateType(objectPropertyDto.FieldType)));
                        }
                    }
                    arrayListViewExcel.Add(tempObjListViewExcel);
                }

                if (isWorkflow) // 添加流程字段
                {
                    JObject tempInstanceNameExcel = new JObject();
                    tempInstanceNameExcel.Add(new JProperty("field", "flow_InstanceName"));
                    tempInstanceNameExcel.Add(new JProperty("name", "流程名称"));
                    tempInstanceNameExcel.Add(new JProperty("fieldType", EExcelFieldType.String));
                    arrayListViewExcel.Add(tempInstanceNameExcel);

                    JObject tempCurrentActivitiesExcel = new JObject();
                    tempCurrentActivitiesExcel.Add(new JProperty("field", "flow_CurrentActivities"));
                    tempCurrentActivitiesExcel.Add(new JProperty("name", "当前活动"));
                    tempCurrentActivitiesExcel.Add(new JProperty("fieldType", EExcelFieldType.String));
                    arrayListViewExcel.Add(tempCurrentActivitiesExcel);

                    JObject tempStatusExcel = new JObject();
                    tempStatusExcel.Add(new JProperty("field", "flow_Status"));
                    tempStatusExcel.Add(new JProperty("name", "流程状态"));
                    tempStatusExcel.Add(new JProperty("fieldType", EExcelFieldType.String));
                    arrayListViewExcel.Add(tempStatusExcel);
                }

                jobjectViewProperty.Remove("excelTemplate");
                jobjectViewProperty.Add("excelTemplate", arrayListViewExcel);
                spriteView.PropertySettings = JsonConvert.SerializeObject(jobjectViewProperty, new JsonSerializerSettings { ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver() });
            }
            if (jobjectViewProperty.ContainsKey("defaultSorting"))
            {
                jobjectViewProperty.Remove("defaultSorting");
                spriteView.PropertySettings = JsonConvert.SerializeObject(jobjectViewProperty, new JsonSerializerSettings { ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver() });
            }
            if (jobjectViewProperty.ContainsKey("excelName"))
            {
                var originExcelName = jobjectViewProperty["excelName"].ToString();
                jobjectViewProperty.Remove("excelName");
                jobjectViewProperty.Add("excelName", ReplaceName(dictObjectNames, dictDescriptions, originExcelName));

                if (jobjectViewProperty.ContainsKey("excelDicts"))
                {
                    jobjectViewProperty.Remove("excelDicts");
                }
                List<ExcelDictInfo> excelDictInfos = new List<ExcelDictInfo>();
                foreach (var tempPropertyDtoAliasInfo in tempPropertyDtoAliasInfos)
                {
                    var objectPropertyDto = tempPropertyDtoAliasInfo.ObjectPropertyDto;
                    var alias = string.IsNullOrEmpty(tempPropertyDtoAliasInfo.Alias) ? "" : $"_{tempPropertyDtoAliasInfo.Alias}";
                    if (!string.IsNullOrWhiteSpace(objectPropertyDto.Dict))
                    {
                        excelDictInfos.Add(new ExcelDictInfo()
                        {
                            dict = objectPropertyDto.Dict,
                            field = objectPropertyDto.Name.ToCamelCase() + alias
                        });
                    }
                }
                if(isWorkflow)
                {
                    excelDictInfos.Add(new ExcelDictInfo()
                    {
                        dict = "instanceStatus",
                        field = "flow_Status"
                    });

                }
                if (excelDictInfos.Count > 0)
                {
                    jobjectViewProperty.Add("excelDicts", JArray.FromObject(excelDictInfos));
                }
                spriteView.PropertySettings = JsonConvert.SerializeObject(jobjectViewProperty, new JsonSerializerSettings { ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver() });

            }
        }

        private Dictionary<string, SpriteObjectDto> GetDictAliasSpriteObjectDto(string viewObjectName)
        {
            var objectNames = viewObjectName.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
            Dictionary<string, SpriteObjectDto> dictAliasObjects = new Dictionary<string, SpriteObjectDto>();
            char index = 'a';
            foreach (var objectName in objectNames)
            {
                var spriteObject = SpriteObjectLocalCache.GetAll(_applicationCode).FirstOrDefault(r => r.Name == objectName);
                if (spriteObject == null)
                {
                    throw new SpriteException($"未找到{objectName}数据库对象名称");
                }

                dictAliasObjects.Add(index.ToString(), spriteObject);
                index = Convert.ToChar(index + 1);
            }

            return dictAliasObjects;
        }

        private string ReplaceName(Dictionary<string, string> dictObjectNames, Dictionary<string, string> dictDescriptions, string oldValue)
        {
            foreach (var dictObjectName in dictObjectNames)
            {
                if (oldValue.IndexOf(dictObjectName.Key) >= 0)
                {
                    oldValue = oldValue.Replace(dictObjectName.Key, dictObjectName.Value);
                }
            }

            foreach (var dictDescription in dictDescriptions)
            {
                if (oldValue.IndexOf(dictDescription.Key) >= 0)
                {
                    oldValue = oldValue.Replace(dictDescription.Key, dictDescription.Value);
                }
            }

            return oldValue;
        }

        private string ReplaceGuid(Dictionary<string, string> dictObjectNames, string strOldGuid, string strNewGuid, string oldValue)
        {
            if (string.IsNullOrEmpty(oldValue))
            {
                return oldValue;
            }

            if (oldValue.IndexOf(strOldGuid) >= 0)
            {
                oldValue = oldValue.Replace(strOldGuid, strNewGuid);
            }

            foreach (var dictObjectName in dictObjectNames)
            {
                if (oldValue.IndexOf(dictObjectName.Key) >= 0)
                {
                    oldValue = oldValue.Replace(dictObjectName.Key, dictObjectName.Value);
                }
            }

            return oldValue;
        }

        private void TryAddNormalFilter(ObjectPropertyDto objectPropertyDto, int index, Guid viewId, List<ListViewFilter> listViewFilters, string alias = "")
        {
            ListViewFilter listViewFilter = new ListViewFilter()
            {
                Id = Guid.NewGuid(),
                FieldName = $"{objectPropertyDto.Name.ToCamelCase()}{alias}",
                FilterType = EFilterType.常规查询,
                LabelValue = objectPropertyDto.Description,
                Order = index.ToString("00"),
                ViewId = viewId
            };

            if (!string.IsNullOrEmpty(objectPropertyDto.Dict))
            {
                listViewFilter.ComponentName = "col-form-dict";
                listViewFilter.ControlSettings = $"{{'dict':'{objectPropertyDto.Dict}','allowClear':true,'style':'width: 170px','componentName':'a-select'}}";
                listViewFilter.DefaultConditionType = EConditionType.等于;
                listViewFilter.AllowConditionTypes = "1";
                listViewFilters.Add(listViewFilter);
            }
            else
            {
                switch (objectPropertyDto.FieldType)
                {
                    case EFieldType.String:
                        listViewFilter.ComponentName = "col-form-common";
                        listViewFilter.ControlSettings = $"{{'componentName':'a-input','style':'width: 170px'}}";
                        listViewFilter.DefaultConditionType = EConditionType.Like;
                        listViewFilter.AllowConditionTypes = "5";
                        listViewFilters.Add(listViewFilter);
                        break;
                    case EFieldType.Date:
                        listViewFilter.ComponentName = "col-form-common";
                        listViewFilter.ControlSettings = "{'componentName':'a-range-picker','valueFormat':'YYYY-MM-DD','style':'width: 200px'}";
                        listViewFilter.DefaultConditionType = EConditionType.Between;
                        listViewFilter.AllowConditionTypes = "3";
                        listViewFilters.Add(listViewFilter);
                        break;
                    case EFieldType.DateTime:
                        listViewFilter.ComponentName = "col-form-common";
                        listViewFilter.ControlSettings = "{'componentName':'a-range-picker','valueFormat':'YYYY-MM-DD','style':'width: 200px'}";
                        listViewFilter.DefaultConditionType = EConditionType.Between;
                        listViewFilter.AllowConditionTypes = "3";
                        listViewFilters.Add(listViewFilter);
                        break;
                    case EFieldType.Text:
                        listViewFilter.ComponentName = "col-form-common";
                        listViewFilter.ControlSettings = $"{{'componentName':'a-input','style':'width: 170px'}}";
                        listViewFilter.DefaultConditionType = EConditionType.Like;
                        listViewFilter.AllowConditionTypes = "5";
                        listViewFilters.Add(listViewFilter);
                        break;
                }
            }
        }

        private void TryAddHightFilter(ObjectPropertyDto objectPropertyDto, int index, Guid viewId, List<ListViewFilter> listViewFilters, string alias = "")
        {
            ListViewFilter listViewFilter = new ListViewFilter()
            {
                Id = Guid.NewGuid(),
                FieldName = $"{objectPropertyDto.Name.ToCamelCase()}{alias}",
                FilterType = EFilterType.高级查询,
                LabelValue = objectPropertyDto.Description,
                Order = index.ToString("00"),
                ViewId = viewId,
                Description = objectPropertyDto.Description,
            };
            if (!string.IsNullOrEmpty(objectPropertyDto.Dict))
            {
                listViewFilter.ComponentName = "SingleDropDown";
                listViewFilter.ControlSettings = $"{{'placeholder':'请选择{objectPropertyDto.Description}'}}";
                listViewFilter.DefaultConditionType = EConditionType.等于;
                listViewFilter.AllowConditionTypes = "1";
                listViewFilter.Source = $"/api/spriteform/common/GetDictItemRemoteInfo?dictCode={objectPropertyDto.Dict}";
                listViewFilters.Add(listViewFilter);
                return;
            }
            switch (objectPropertyDto.FieldType)
            {
                case EFieldType.String:
                    listViewFilter.ComponentName = "TextBox";
                    listViewFilter.ControlSettings = $"{{'placeholder':'请输入{objectPropertyDto.Description}'}}";
                    listViewFilter.DefaultConditionType = EConditionType.Like;
                    listViewFilter.AllowConditionTypes = "5;1";
                    listViewFilters.Add(listViewFilter);
                    break;
                case EFieldType.Int:
                    listViewFilter.ComponentName = "TextBox";
                    listViewFilter.ControlSettings = $"{{'placeholder':'请输入{objectPropertyDto.Description}'}}";
                    listViewFilter.DefaultConditionType = EConditionType.等于;
                    listViewFilter.AllowConditionTypes = "1;2;3;6;7;8;9";
                    listViewFilters.Add(listViewFilter);
                    break;
                case EFieldType.Bool:
                    listViewFilter.ComponentName = "Radio";
                    listViewFilter.ControlSettings = $"{{'placeholder':'请输入{objectPropertyDto.Description}'}}";
                    listViewFilter.DefaultConditionType = EConditionType.等于;
                    listViewFilter.AllowConditionTypes = "1";
                    listViewFilters.Add(listViewFilter);
                    break;
                case EFieldType.Date:
                    listViewFilter.ComponentName = "DateTime";
                    listViewFilter.ControlSettings = $"{{'placeholder':'请输入{objectPropertyDto.Description}'}}";
                    listViewFilter.DefaultConditionType = EConditionType.Between;
                    listViewFilter.AllowConditionTypes = "3;6;7;8;9";
                    listViewFilters.Add(listViewFilter);
                    break;
                case EFieldType.DateTime:
                    listViewFilter.ComponentName = "DateTime";
                    listViewFilter.ControlSettings = $"{{'placeholder':'请输入{objectPropertyDto.Description}'}}";
                    listViewFilter.DefaultConditionType = EConditionType.Between;
                    listViewFilter.AllowConditionTypes = "3;6;7;8;9";
                    listViewFilters.Add(listViewFilter);
                    break;
                case EFieldType.Text:
                    listViewFilter.ComponentName = "TextBox";
                    listViewFilter.ControlSettings = $"{{'placeholder':'请输入{objectPropertyDto.Description}'}}";
                    listViewFilter.DefaultConditionType = EConditionType.Like;
                    listViewFilter.AllowConditionTypes = "5;1";
                    listViewFilters.Add(listViewFilter);
                    break;
                case EFieldType.Float:
                    listViewFilter.ComponentName = "TextBox";
                    listViewFilter.ControlSettings = $"{{'placeholder':'请输入{objectPropertyDto.Description}'}}";
                    listViewFilter.DefaultConditionType = EConditionType.等于;
                    listViewFilter.AllowConditionTypes = "1;2;3;6;7;8;9";
                    listViewFilters.Add(listViewFilter);
                    break;
                case EFieldType.Decimal:
                    listViewFilter.ComponentName = "TextBox";
                    listViewFilter.ControlSettings = $"{{'placeholder':'请输入{objectPropertyDto.Description}'}}";
                    listViewFilter.DefaultConditionType = EConditionType.等于;
                    listViewFilter.AllowConditionTypes = "1;2;3;6;7;8;9";
                    listViewFilters.Add(listViewFilter);
                    break;
            }
        }

        private void CalculateId(Guid? oldId)
        {
            if (!oldId.HasValue)
            {
                return;
            }
            if (!idMapes.ContainsKey(oldId.Value))
            {
                if (oldId.Value == Guid.Empty)
                {
                    idMapes.Add(oldId.Value, Guid.Empty);
                }
                else
                {
                    idMapes.Add(oldId.Value, Guid.NewGuid());
                }
            }
        }

        public static void CalculateFormViewVueInfo(FormViewVueInfos formViewVueInfos, Dictionary<Guid, SpriteFormVueDto> spriteFormVueDtos, Dictionary<Guid, SpriteViewVueDto> spriteViewVueDtos, Guid id, bool isForm)
        {
            if (isForm)
            {
                spriteFormVueDtos.TryGetValue(id, out var spriteFormVueDto);
                if (spriteFormVueDtos.ContainsKey(id) && !formViewVueInfos.FormDatas.Exists(r => r.Id == spriteFormVueDto.Id))
                {
                    formViewVueInfos.FormDatas.Add(spriteFormVueDto);
                    foreach (var relationInfo in (spriteFormVueDto.RelationInfos as List<RelasionInfo>))
                    {
                        CalculateFormViewVueInfo(formViewVueInfos, spriteFormVueDtos, spriteViewVueDtos, relationInfo.Id, relationInfo.RelationType == 1);
                    }
                }
            }
            else
            {
                spriteViewVueDtos.TryGetValue(id, out var spriteViewVueDto);
                if (spriteViewVueDto != null && !formViewVueInfos.FormDatas.Exists(r => r.Id == spriteViewVueDto.Id))
                {
                    formViewVueInfos.ViewDatas.Add(spriteViewVueDto);
                    foreach (var relationInfo in (spriteViewVueDto.RelationInfos as List<RelasionInfo>))
                    {
                        CalculateFormViewVueInfo(formViewVueInfos, spriteFormVueDtos, spriteViewVueDtos, relationInfo.Id, relationInfo.RelationType == 1);
                    }
                }
            }
        }

        private EExcelFieldType GetExcelFieldType(EFieldType fieldType)
        {
            switch (fieldType)
            {
                case EFieldType.String:
                    return EExcelFieldType.String;
                case EFieldType.Int:
                    return EExcelFieldType.Int;
                case EFieldType.Bool:
                    return EExcelFieldType.Bool;
                case EFieldType.Date:
                    return EExcelFieldType.Date;
                case EFieldType.DateTime:
                    return EExcelFieldType.DateTime;
                case EFieldType.AutoNumber:
                    return EExcelFieldType.Int;
                case EFieldType.AutoGuid:
                    return EExcelFieldType.Guid;
                case EFieldType.Guid:
                    return EExcelFieldType.Guid;
                case EFieldType.Text:
                    return EExcelFieldType.String;
                case EFieldType.Float:
                    return EExcelFieldType.Double;
                case EFieldType.Decimal:
                    return EExcelFieldType.Double;
            }
            return EExcelFieldType.String;
        }

        private EExcelValidateType GetNormalExcelValidateType(EFieldType fieldType)
        {
            switch (fieldType)
            {
                case EFieldType.Int:
                    return EExcelValidateType.Int;
                case EFieldType.Bool:
                    return EExcelValidateType.Int;
                case EFieldType.Date:
                    return EExcelValidateType.Date;
                case EFieldType.DateTime:
                    return EExcelValidateType.Datetime;
                case EFieldType.AutoNumber:
                    return EExcelValidateType.Int;
                case EFieldType.Float:
                    return EExcelValidateType.Double;
                case EFieldType.Decimal:
                    return EExcelValidateType.Double;
            }
            return EExcelValidateType.Empty;
        }

        #endregion
    }

    internal class ExcelDictInfo
    {
        public string dict { get; set; }
        public string field { get; set; }
    }

    internal class CustomerRender
    {
        public string customRender { get; set; }
    }

    internal class ListViewExcelDesign
    {
        public string field { get; set; }
        public string name { get; set; }
        public EExcelFieldType fieldType { get; set; }
        public int cellLength { get; set; }
        public string exportComments { get; set; }
        public bool isRequred { get; set; }
        public EExcelValidateType validateType { get; set; }
        public string validateValue { get; set; }
    }

    public enum EExcelFieldType
    {
        Int = 1,
        Double = 2,
        Guid = 3,
        Bool = 4,
        String = 5,
        Date = 6,
        DateTime = 7
    }

    public enum EExcelValidateType
    {
        Empty = 0,
        Int = 1,
        Decimal = 2,
        Double = 3,
        String = 4,
        Phone = 5,
        Idcard = 6,
        Email = 7,
        Mobile = 8,
        Date = 9,
        Datetime = 10,
        Dict = 11,
        Regular = 99
    }

    internal class TempPropertyDtoAliasInfo
    {
        public ObjectPropertyDto ObjectPropertyDto { get; set; }
        public string Alias { get; set; }
    }
}
